<?php
use vierbergenlars\SemVer\version;
use vierbergenlars\SemVer\SemVerException;
class PackageModel {
	const ERR_FILE = 1;
	const ERR_JSON = 2;
	const ERR_NAME = 3;
	const ERR_VER = 4;
	public static function get($id, $version = NULL, $stable = NULL) {
		$sql = 'SELECT * FROM xpm_package WHERE pid = ? AND ';
		$data = [$id];
		if ($version !== NULL) {
			$sql .= 'version = ?';
			$data[] = $version;
		}
		if ($stable !== NULL) {
			$sql .= 'stable = ?';
			$data[] = $stable;
		}
		$rs = Database::getInstance()->getOne($sql, $data);
		return empty($rs) ? NULL : $rs;
	}
	public static function add($file) {
		if (!is_file($file)) {
			return self::ERR_FILE;
		}
		$zip = new ZipArchive;
		$res = $zip->open($file, ZipArchive::CREATE);
		if (!$res) {
			return self::ERR_FILE;
		}
		$info = json_decode($zip->getFromName('xpm.config.json'), 1);
		if (!is_array($info)) {
			return self::ERR_JSON;
		}
		//解析基本信息
		$name = $info['name'];
		$description = $info['description'];
		$type = $info['type'];
		$version = $info['version'];
		$author = $info['author'];
		$license = $info['license'];
		$stable = preg_match('/(alpha|beta)/i', $info['version']) ? 0 : 1;
		$time = date('Y-m-d H:i:s');
		$homepage = $info['homepage'];
		if (empty($name)) {
			return self::ERR_NAME;
		}
		$zip->close();
		//检查版本号是否合法
		try {
			$semver = new version($version); //SemVerException thrown
		} catch (SemVerException $e) {
			return self::ERR_VER;
		}
		$version = $semver->getVersion();
		//生成文件名和ID
		$pid = md5(uniqid($name, TRUE));
		mkdir(PKG_DIR . $pid, 0777);
		$filename = $pid . '/' . md5_file($file) . '.zip';
		$fullPath = PKG_DIR . $filename;
		//存放文件
		rename($file, $fullPath);
		//入库
		$sql = 'INSERT INTO `xpm_package`(`pid`, `type`, `name`, `version`, `description`, `author`, `license`, `download`, `stable`, `time`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)';
		$data = [$pid, $type, $name, $version, $description, $author, $license, $filename, $stable, $time];
		Database::getInstance()->query($sql, $data);
		$id = Database::getInstance()->getLastId();
		$sql = 'INSERT INTO `xpm_package_meta`(`id`, `newest`, `name`, `version`, `homepage`) VALUES (?, ?, ?, ?, ?)';
		$data = [$pid, $id, $name, $version, $homepage];
		Database::getInstance()->query($sql, $data);
		return $pid;
	}
	public static function update($pid, $file) {
		if (!is_file($file)) {
			return self::ERR_FILE;
		}
		$zip = new ZipArchive;
		$res = $zip->open($file, ZipArchive::CREATE);
		if (!$res) {
			return self::ERR_FILE;
		}
		$info = json_decode($zip->getFromName('xpm.config.json'), 1);
		if (!is_array($info)) {
			return self::ERR_JSON;
		}
		//解析基本信息
		$name = $info['name'];
		$description = $info['description'];
		$type = $info['type'];
		$version = $info['version'];
		$author = $info['author'];
		$license = $info['license'];
		$stable = preg_match('/(alpha|beta)/i', $info['version']) ? 0 : 1;
		$time = date('Y-m-d H:i:s');
		$homepage = $info['homepage'];
		if (empty($name)) {
			return self::ERR_NAME;
		}
		$zip->close();
		//对比版本号
		try {
			$semver = new version($version); //SemVerException thrown
		} catch (SemVerException $e) {
			return self::ERR_VER;
		}
		$version = $semver->getVersion();
		$oldVersion = Database::getInstance()->getOne('SELECT version FROM `xpm_package_meta` WHERE id = ?', [$pid]);
		if (!version_compare($oldVersion['version'], $version, '<')) {
			return self::ERR_VER;
		}
		//生成文件名
		$filename = $pid . '/' . md5_file($file) . '.zip';
		$fullPath = PKG_DIR . $filename;
		//存放文件
		rename($file, $fullPath);
		//入库
		$sql = 'INSERT INTO `xpm_package`(`pid`, `type`, `name`, `version`, `description`, `author`, `license`, `download`, `stable`, `time`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)';
		$data = [$pid, $type, $name, $version, $description, $author, $license, $filename, $stable, $time];
		Database::getInstance()->query($sql, $data);
		$id = Database::getInstance()->getLastId();
		$sql = 'UPDATE `xpm_package_meta` SET `newest` = ?, `name` = ?, `version` = ?, `homepage` = ? WHERE id = ?';
		$data = [$id, $name, $version, $homepage, $pid];
		Database::getInstance()->query($sql, $data);
		return NULL;
	}
}